package com.goingup.domain;

/**
 * Represents the direction of the elevator
 * @author pcresswell
 *
 */
public class Vector {
	public enum Direction
	{
		NONE,
		UP,
		DOWN
	}
	
	
	private Floor targetFloor;
	private Direction currentDirection=Direction.NONE;
	private Floor currentFloor;
	private final long moveTimeInMilliseconds=1000; 
	
	public Vector(Floor currentFloor)
	{
		this.currentFloor = currentFloor;
	}
	public void setTargetFloor(Floor targetFloor)
	{
		this.targetFloor = targetFloor;
		if (getCurrentFloor().isAbove(targetFloor))
			currentDirection = Direction.DOWN;
		else if(getCurrentFloor().isBelow(targetFloor))
			currentDirection = Direction.UP;
		else
			currentDirection=Direction.NONE;
	}
	public Direction getCurrentDirection()
	{
		return currentDirection;
	}
	public void move()
	{
		
		simulateMotionTime();
		incrementFloor();
		System.out.print("Moving to floor: " + currentFloor.getNumber() + "\n");
	}
	private  void incrementFloor() {
		currentFloor = currentFloor.next(currentDirection);
	}
	private void simulateMotionTime()  {
		try {
			Thread.sleep(this.moveTimeInMilliseconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void stop()
	{
		currentDirection = Direction.NONE;
	}
	public Floor getCurrentFloor()
	{
		return this.currentFloor;
	}
	public boolean atTargetFloor()
	{
		return this.getCurrentFloor().equals(targetFloor);
	}
	/**
	 * Returns an integer value that represents a unitless distance from its current position
	 * to the desired floor.  Takes into account its current position, current target and 
	 * the given floor
	 * @return
	 */
	public int distanceFrom(Floor floor)
	{
		if(targetFloor==null)
		{
			return distanceBetweenFloors(getCurrentFloor(), floor);
		}
		else if (floor.isAbove(currentFloor)&& floor.isBelow(targetFloor) 
		   && Direction.UP.equals(currentDirection))
		{
			return distanceBetweenFloors(getCurrentFloor(), floor);
		}
		else if (floor.isBelow(currentFloor)&& floor.isAbove(targetFloor) 
		   && Direction.DOWN.equals(currentDirection))
		{
			return distanceBetweenFloors(getCurrentFloor(), floor);
		}
		else
		{
			return distanceBetweenFloors(getCurrentFloor(), targetFloor) + 
				   distanceBetweenFloors(targetFloor, floor);
		}
	}
	private int distanceBetweenFloors(Floor floorOne, Floor floorTwo)
	{
		return Math.abs(floorOne.getNumber() - floorTwo.getNumber());
	}
	
}


